home *** CD-ROM | disk | FTP | other *** search
Oberon Text | 1994-07-07 | 22.1 KB | 533 lines | [.Ob./.Ob4] |
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- Syntax10b.Scn.Fnt
- FoldElems
- Syntax10.Scn.Fnt
- BEGIN X := SHORT(x); Y := SHORT(y)
- END StdScale;
- Syntax10.Scn.Fnt
- BEGIN IF (F.X <= X) & (X < F.X + F.W) & (F.Y <= Y) & (Y < F.Y + F.H) THEN Pluto.ReplConst(X, Y, 1, 1) END
- END PDot;
- Syntax10.Scn.Fnt
- BEGIN Display.ReplConstC(F, col, X, Y, W, H, mode)
- END DBlock;
- Syntax10.Scn.Fnt
- BEGIN
- IF X < F.X THEN DEC(W, F.X - X); X := F.X END;
- IF X+W > F.X + F.W THEN W := F.X + F.W - X END;
- IF Y < F.Y THEN DEC(H, F.Y - Y); Y := F.Y END;
- IF Y+H > F.Y + F.H THEN H := F.Y + F.H - Y END;
- IF (W > 0) & (H > 0) THEN Pluto.ReplConst(X, Y, W, H) END
- END PBlock;
- Syntax10.Scn.Fnt
- BEGIN
- IF F = Printer THEN
- Dot := PDot;
- Block := PBlock;
- ELSE
- Dot := Display.DotC;
- IF pat = 0 THEN Block := DBlock
- ELSE Block := Display.ReplPatternC
- END
- END;
- IF col = invert THEN mode := Display.invert
- ELSE mode := Display.replace
- END
- END SetUp;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- FoldElems
- Syntax10.Scn.Fnt
- BEGIN min := x1; max := x1;
- IF x2 < min THEN min := x2 ELSIF x2 > max THEN max := x2 END;
- IF x3 < min THEN min := x3 ELSIF x3 > max THEN max := x3 END;
- IF x4 < min THEN min := x4 ELSIF x4 > max THEN max := x4 END
- END MinMax;
- Syntax10.Scn.Fnt
- BEGIN
- p.x := x1; p.dx := x2-x1;
- IF p.dx > 0 THEN p.inx := 1 ELSIF p.dx < 0 THEN p.inx := -1; p.dx := -p.dx ELSE p.inx := 0 END;
- p.y := y1; p.dy := y2-y1;
- IF p.dy > 0 THEN p.iny := 1 ELSIF p.dy < 0 THEN p.iny := -1; p.dy := -p.dy ELSE p.iny := 0 END;
- p.d := p.dy - p.dx; p.dx := 2*p.dx; p.dy := 2*p.dy;
- END InitLineParms;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- BEGIN (* H = (d(x, y) := (2*x - 2*x1 + 1)*dy - (2*y - 2*y1 + 1)*dx < 0) *)
- WHILE p.d < 0 DO INC(p.x, p.inx); INC(p.d, p.dy) END;
- p.drawX := p.x; p.drawY := p.iny DIV 2 + p.y;
- DEC(p.d, p.dx); INC(p.y, p.iny);
- END LineStep;
- (* B. Stamm *)
- TYPE LineParms = RECORD x, y, d, dx, dy, inx, iny, drawX, drawY: INTEGER END;
- VAR left, right: LineParms;
- X0, Y0, X1, Y1, X2, Y2, X3, Y3, X4, Y4, X, Y, RHS2, RHS3, Xmin, Xmax, Ymin, Ymax: INTEGER;
- Dot: DotProc; Block: BlockProc; mode: INTEGER;
- PROCEDURE MinMax(x1, x2, x3, x4: INTEGER; VAR min, max: INTEGER);
- PROCEDURE InitLineParms(x1, y1, x2, y2: INTEGER; VAR p: LineParms);
- PROCEDURE LineStep(VAR p: LineParms);
- BEGIN
- Scale(F, x1, y1, X1, Y1);
- Scale(F, x2, y2, X2, Y2);
- Scale(F, x3, y3, X3, Y3);
- Scale(F, x4, y4, X4, Y4);
- MinMax(X1, X2, X3, X4, Xmin, Xmax);
- MinMax(Y1, Y2, Y3, Y4, Ymin, Ymax);
- IF (F.X < Xmax) & (Xmin < F.X + F.W) & (F.Y < Ymax) & (Ymin < F.Y + F.H) THEN (* quadrangle may be visible *)
- SetUp(F, Dot, Block, col, mode, pat);
- Scale(F, 0, 0, X0, Y0);
- IF (Y1 > Y2) OR (Y1 = Y2) & (X1 > X2) THEN X := X1; X1 := X2; X2 := X; Y := Y1; Y1 := Y2; Y2 := Y END;
- IF (Y2 > Y3) OR (Y2 = Y3) & (X2 > X3) THEN X := X2; X2 := X3; X3 := X; Y := Y2; Y2 := Y3; Y3 := Y END;
- IF (Y3 > Y4) OR (Y3 = Y4) & (X3 > X4) THEN X := X3; X3 := X4; X4 := X; Y := Y3; Y3 := Y4; Y4 := Y END;
- IF (Y1 > Y2) OR (Y1 = Y2) & (X1 > X2) THEN X := X1; X1 := X2; X2 := X; Y := Y1; Y1 := Y2; Y2 := Y END;
- IF (Y2 > Y3) OR (Y2 = Y3) & (X2 > X3) THEN X := X2; X2 := X3; X3 := X; Y := Y2; Y2 := Y3; Y3 := Y END;
- IF (Y1 > Y2) OR (Y1 = Y2) & (X1 > X2) THEN X := X1; X1 := X2; X2 := X; Y := Y1; Y1 := Y2; Y2 := Y END;
- IF LONG(X2-X1)*LONG(Y4-Y1) > LONG(Y2-Y1)*LONG(X4-X1) THEN RHS2 := 2 ELSE RHS2 := 0 END;
- IF LONG(X3-X1)*LONG(Y4-Y1) > LONG(Y3-Y1)*LONG(X4-X1) THEN RHS3 := 1 ELSE RHS3 := 0 END;
- CASE RHS2 + RHS3 OF
- | 0: InitLineParms(X1, Y1, X2, Y2, left); InitLineParms(X1, Y1, X4, Y4, right);
- | 1: InitLineParms(X1, Y1, X2, Y2, left); InitLineParms(X1, Y1, X3, Y3, right);
- | 2: InitLineParms(X1, Y1, X3, Y3, left); InitLineParms(X1, Y1, X2, Y2, right);
- | 3: InitLineParms(X1, Y1, X4, Y4, left); InitLineParms(X1, Y1, X2, Y2, right);
- END;
- WHILE left.y # Y2 DO
- LineStep(left); LineStep(right);
- Block(F, col, pat, left.drawX, left.drawY, right.drawX-left.drawX, 1, X0, Y0, mode)
- END;
- CASE RHS2 + RHS3 OF
- | 0: InitLineParms(X2, Y2, X3, Y3, left);
- | 1: InitLineParms(X2, Y2, X4, Y4, left);
- | 2: InitLineParms(X2, Y2, X4, Y4, right);
- | 3: InitLineParms(X2, Y2, X3, Y3, right);
- END;
- WHILE left.y # Y3 DO
- LineStep(left); LineStep(right);
- Block(F, col, pat, left.drawX, left.drawY, right.drawX-left.drawX, 1, X0, Y0, mode)
- END;
- CASE RHS2 + RHS3 OF
- | 0, 2: InitLineParms(X3, Y3, X4, Y4, left);
- | 1, 3: InitLineParms(X3, Y3, X4, Y4, right);
- END;
- WHILE left.y # Y4 DO
- LineStep(left); LineStep(right);
- Block(F, col, pat, left.drawX, left.drawY, right.drawX-left.drawX, 1, X0, Y0, mode)
- END
- END
- END Quadrangle;
- Syntax10.Scn.Fnt
- FoldElems
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- VAR x, y, dx, dy, d, inc, L, B, R, T, Xmin, Xmax, Ymin, Ymax: INTEGER;
- Dot: DotProc; Block: BlockProc; mode: INTEGER;
- BEGIN
- L := F.X; B := F.Y; R := F.X + F.W; T := F.Y + F.H;
- IF X0 < X1 THEN Xmin := X0; Xmax := X1 ELSE Xmin := X1; Xmax := X0 END;
- IF Y0 < Y1 THEN Ymin := Y0; Ymax := Y1 ELSE Ymin := Y1; Ymax := Y0 END;
- IF (L <= Xmax) & (Xmin < R) & (B <= Ymax) & (Ymin < T) THEN (* line may be visible *)
- SetUp(F, Dot, Block, col, mode, pat);
- IF Xmin = Xmax THEN Block(F, col, pat, Xmin, Ymin, 1, Ymax-Ymin+1, col, 0, 0)
- ELSIF Ymin = Ymax THEN Block(F, col, pat, Xmin, Ymin, Xmax-Xmin+1, 1, col, 0, 0)
- ELSE
- IF (Y1-Y0) < (X0-X1) THEN x := X0; X0 := X1; X1 := x; y := Y0; Y0 := Y1; Y1 := y END;
- dx := 2*(X1-X0); dy := 2*(Y1-Y0); x := X0; y := Y0; inc := 1;
- IF (L <= Xmin) & (Xmax < R) & (B <= Ymin) & (Ymax < T) THEN (* no clipping *)
- IF dy > dx THEN d := dy DIV 2;
- IF dx < 0 THEN inc := -1; dx := -dx END;
- WHILE y <= Y1 DO
- Dot(F, col, x, y, mode);
- INC(y); DEC(d, dx);
- IF d < 0 THEN INC(d, dy); INC(x, inc) END
- END
- ELSE d := dx DIV 2;
- IF dy < 0 THEN inc := -1; dy := -dy END;
- WHILE x <= X1 DO
- Dot(F, col, x, y, mode);
- INC(x); DEC(d, dy);
- IF d < 0 THEN INC(d, dx); INC(y, inc) END
- END
- END
- ELSE (* dot-wise clipping *)
- IF dy > dx THEN d := dy DIV 2;
- IF dx < 0 THEN inc := -1; dx := -dx END;
- WHILE y <= Y1 DO
- IF (L <= x) & (x < R) & (B <= y) & (y < T) THEN Dot(F, col, x, y, mode) END;
- INC(y); DEC(d, dx);
- IF d < 0 THEN INC(d, dy); INC(x, inc) END
- END
- ELSE d := dx DIV 2;
- IF dy < 0 THEN inc := -1; dy := -dy END;
- WHILE x <= X1 DO
- IF (L <= x) & (x < R) & (B <= y) & (y < T) THEN Dot(F, col, x, y, mode) END;
- INC(x); DEC(d, dy);
- IF d < 0 THEN INC(d, dx); INC(y, inc) END
- END
- END
- END
- END
- END
- END HairLine;
- Syntax10i.Scn.Fnt
- VAR X1, Y1, X2, Y2: INTEGER; dx, dy, c: LONGREAL; u1, v1, u2, v2, u3, v3, u4, v4: LONGINT;
- PROCEDURE HairLine (F: Display.Frame; X0, Y0, X1, Y1, col: INTEGER);
- BEGIN
- IF d <= 0 THEN
- Scale(F, x1, y1, X1, Y1);
- Scale(F, x2, y2, X2, Y2);
- HairLine(F, X1, Y1, X2, Y2, col)
- ELSE (* thick line *)
- dx := x2-x1; dy := y2-y1; c := 2 * MathL.sqrt(dx*dx + dy*dy);
- IF c > 0 THEN c := d/c;
- dx := dx*c; dy := dy*c;
- u1 := ENTIER(x1-dy); v1 := ENTIER(y1+dx);
- u2 := ENTIER(x1+dy); v2 := ENTIER(y1-dx);
- u3 := ENTIER(x2-dy); v3 := ENTIER(y2+dx);
- u4 := ENTIER(x2+dy); v4 := ENTIER(y2-dx);
- Quadrangle(F, u1, v1, u2, v2, u3, v3, u4, v4, pat, col)
- END
- END
- END Line;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- VAR X0, Y0, L, B, R, T, Li, Bi, Ri, Ti: INTEGER;
- Dot: DotProc; Block: BlockProc; mode: INTEGER;
- BEGIN
- Scale(F, x, y, L, B);
- Scale(F, x+w, y+h, R, T);
- IF (F.X < R) & (L < F.X + F.W) & (F.Y < T) & (B < F.Y + F.H) THEN (* rectangle may be visible *)
- SetUp(F, Dot, Block, col, mode, pat);
- IF d <= 0 THEN (* hair rectangle *)
- Li := L+1; Bi := B+1; Ri := R-1; Ti := T-1;
- col := col MOD 256; X0 := 0; Y0 := 0 (* ignore pattern *)
- ELSE (* thick rectangle *)
- Scale(F, 0, 0, X0, Y0);
- Scale(F, x+d, y+d, Li, Bi);
- Scale(F, x+w-d, y+h-d, Ri, Ti)
- END;
- IF (Li < Ri) & (Bi < Ti) THEN
- Block(F, col, pat, L, B, R-L, Bi-B, X0, Y0, mode);
- Block(F, col, pat, L, Ti, R-L, T-Ti, X0, Y0, mode);
- Block(F, col, pat, L, Bi, Li-L, Ti-Bi, X0, Y0, mode);
- Block(F, col, pat, Ri, Bi, R-Ri, Ti-Bi, X0, Y0, mode)
- ELSE Block(F, col, pat, L, B, R-L, T-B, X0, Y0, mode)
- END
- END
- END Rect;
- Syntax10.Scn.Fnt
- FoldElems
- Syntax10.Scn.Fnt
- FoldElems
- Syntax10.Scn.Fnt
- BEGIN
- Dot(F, col, x1, y1, mode);
- Dot(F, col, x1, y2, mode);
- Dot(F, col, x2, y1, mode);
- Dot(F, col, x2, y2, mode)
- END Dot4;
- Syntax10.Scn.Fnt
- BEGIN
- IF (L <= x1) & (x1 < R) THEN
- IF (B <= y1) & (y1 < T) THEN Dot(F, col, x1, y1, mode) END;
- IF (B <= y2) & (y2 < T) THEN Dot(F, col, x1, y2, mode) END;
- END;
- IF (L <= x2) & (x2 < R) THEN
- IF (B <= y1) & (y1 < T) THEN Dot(F, col, x2, y1, mode) END;
- IF (B <= y2) & (y2 < T) THEN Dot(F, col, x2, y2, mode) END;
- END
- END Dot4c;
- Syntax10i.Scn.Fnt
- VAR x, y, dx, dy, d, L, B, Rt, T: INTEGER;
- PROCEDURE Dot4 (x1, x2, y1, y2: INTEGER);
- PROCEDURE Dot4c (x1, x2, y1, y2: INTEGER);
- BEGIN
- L := F.X; B := F.Y; Rt := F.X + F.W; T := F.Y + F.H;
- IF (L < X+R) & (X-R < Rt) & (B < Y+R) & (Y-R < T) THEN (* circle may be visible *)
- x := R-1; y := 0; dx := 8*(x-1); dy := 8*y+4; d := 3 - 4*R;
- IF (L <= X-R) & (X+R <= Rt) & (B <= Y-R) & (Y+R <= T) THEN (* no clipping *)
- WHILE x > y DO
- Dot4(X-x-1, X+x, Y-y-1, Y+y);
- Dot4(X-y-1, X+y, Y-x-1, Y+x);
- INC(d, dy); INC(dy, 8); INC(y);
- IF d >= 0 THEN DEC(d, dx); DEC(dx, 8); DEC(x) END
- END;
- IF x = y THEN Dot4(X-x-1, X+x, Y-y-1, Y+y) END
- ELSE (* dot-wise clipping *)
- WHILE x > y DO
- Dot4c(X-x-1, X+x, Y-y-1, Y+y);
- Dot4c(X-y-1, X+y, Y-x-1, Y+x);
- INC(d, dy); INC(dy, 8); INC(y);
- IF d >= 0 THEN DEC(d, dx); DEC(dx, 8); DEC(x) END
- END;
- IF x = y THEN Dot4c(X-x-1, X+x, Y-y-1, Y+y) END
- END
- END
- END HairCircle;
- Syntax10.Scn.Fnt
- FoldElems
- Syntax10.Scn.Fnt
- BEGIN
- Dot(F, col, x1, y1, mode);
- Dot(F, col, x1, y2, mode);
- Dot(F, col, x2, y1, mode);
- Dot(F, col, x2, y2, mode)
- END Dot4;
- Syntax10.Scn.Fnt
- BEGIN
- IF (L <= x1) & (x1 < R) THEN
- IF (Bt <= y1) & (y1 < T) THEN Dot(F, col, x1, y1, mode) END;
- IF (Bt <= y2) & (y2 < T) THEN Dot(F, col, x1, y2, mode) END;
- END;
- IF (L <= x2) & (x2 < R) THEN
- IF (Bt <= y1) & (y1 < T) THEN Dot(F, col, x2, y1, mode) END;
- IF (Bt <= y2) & (y2 < T) THEN Dot(F, col, x2, y2, mode) END;
- END
- END Dot4c;
- Syntax10i.Scn.Fnt
- VAR x, y, L, Bt, R, T: INTEGER; d, dx, dy, x2, y2, a, a2, a8, b, b2, b8: LONGINT;
- PROCEDURE Dot4 (x1, x2, y1, y2: INTEGER);
- PROCEDURE Dot4c (x1, x2, y1, y2: INTEGER);
- BEGIN
- IF (A > 0) & (B > 0) THEN
- L := F.X; Bt := F.Y; R := F.X + F.W; T := F.Y + F.H;
- IF (L < X+A) & (X-A < R) & (Bt < Y+B) & (Y-B < T) THEN (* ellipse may be visible *)
- a := A-1; a2 := a*a; a8 := 8*a2; b := B-1; b2 := b*b; b8 := 8*b2;
- x := A-1; y := 0; x2 := a*b2; y2 := 0; dx := b8*(a-1); dy := 4*a2; d := b2*(1- 4*a);
- IF (L <= X-A) & (X+A <= R) & (Bt <= Y-B) & (Y+B <= T) THEN (* no clipping *)
- WHILE y2 < x2 DO
- Dot4(X-x-1, X+x, Y-y-1, Y+y);
- INC(d, dy); INC(dy, a8); INC(y); INC(y2, a2);
- IF d >= 0 THEN DEC(d, dx); DEC(dx, b8); DEC(x); DEC(x2, b2) END
- END;
- INC(d, 4*(x2+y2) - b2+a2);
- WHILE x >= 0 DO
- Dot4(X-x-1, X+x, Y-y-1, Y+y);
- DEC(d, dx); DEC(dx, b8); DEC(x);
- IF d < 0 THEN INC(d, dy); INC(dy, a8); INC(y) END
- END
- ELSE (* dot-wise clipping *)
- WHILE y2 < x2 DO
- Dot4c(X-x-1, X+x, Y-y-1, Y+y);
- INC(d, dy); INC(dy, a8); INC(y); INC(y2, a2);
- IF d >= 0 THEN DEC(d, dx); DEC(dx, b8); DEC(x); DEC(x2, b2) END
- END;
- INC(d, 4*(x2+y2)-b2+a2);
- WHILE x >= 0 DO
- Dot4c(X-x-1, X+x, Y-y-1, Y+y);
- DEC(d, dx); DEC(dx, b8); DEC(x);
- IF d < 0 THEN INC(d, dy); INC(dy, a8); INC(y) END
- END
- END
- END
- END
- END HairEllipse;
- Syntax10.Scn.Fnt
- BEGIN
- Block(F, col, pat, x, y1, w, h, X0, Y0, mode);
- Block(F, col, pat, x, y2, w, h, X0, Y0, mode)
- END Line2;
- Syntax10.Scn.Fnt
- VAR yt: INTEGER;
- BEGIN yt := y1+h;
- IF y1 < 0 THEN y1 := 0 END;
- IF yt > LEN(line) THEN yt := LEN(line) END;
- WHILE y1 < yt DO line[y1].x1 := x; line[y1].x2 := x; line[y1].x3 := x; line[y1].x4 := x+w; INC(y1) END;
- yt := y2+h;
- IF y2 < 0 THEN y2 := 0 END;
- IF yt > LEN(line) THEN yt := LEN(line) END;
- WHILE y2 < yt DO line[y2].x1 := x; line[y2].x2 := x; line[y2].x3 := x; line[y2].x4 := x+w; INC(y2) END
- END Line2o;
- Syntax10.Scn.Fnt
- VAR yt: INTEGER;
- BEGIN yt := y1+h;
- IF y1 < 0 THEN y1 := 0 END;
- IF yt > LEN(line) THEN yt := LEN(line) END;
- WHILE y1 < yt DO line[y1].x2 := x; line[y1].x3 := x+w; INC(y1) END;
- yt := y2+h;
- IF y2 < 0 THEN y2 := 0 END;
- IF yt > LEN(line) THEN yt := LEN(line) END;
- WHILE y2 < yt DO line[y2].x2 := x; line[y2].x3 := x+w; INC(y2) END
- END Line2i;
- Syntax10.Scn.Fnt
- VAR yt, x1, x2, x3, x4: INTEGER;
- BEGIN yt := y+h;
- IF y < 0 THEN y := 0 END;
- IF yt > LEN(line) THEN yt := LEN(line) END;
- WHILE y < yt DO
- x1 := line[y].x1; x2 := line[y].x2; x3 := line[y].x3; x4 := line[y].x4;
- IF x2 < x3 THEN
- Block(F, col, pat, x1, y0+y, x2-x1, 1, X0, Y0, mode);
- Block(F, col, pat, x3, y0+y, x4-x3, 1, X0, Y0, mode)
- ELSE Block(F, col, pat, x1, y0+y, x4-x1, 1, X0, Y0, mode)
- END;
- INC(y)
- END
- END ScanLines;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- VAR x, y, d, dx, dy, yb: INTEGER;
- BEGIN DEC(R); DEC(Ri);
- x := R; y := 0; dx := 8*(x-1); dy := 8*y+4; d := 1 - 4*R; yb := 0;
- IF Ri < 0 THEN (* filled circle *)
- WHILE x > y DO
- INC(d, dy); INC(dy, 8); INC(y);
- IF d >= 0 THEN
- Line2(F, X-x-1, Y-y, Y+yb, 2*(x+1), y-yb, col, X0, Y0);
- Line2(F, X-y, Y-x-1, Y+x, 2*y, 1, col, X0, Y0);
- DEC(d, dx); DEC(dx, 8); DEC(x); yb := y
- END
- END;
- IF x = y THEN INC(y); Line2(F, X-x-1, Y-y, Y+yb, 2*(x+1), y-yb, col, X0, Y0) END
- ELSE (* outer circle *)
- DEC(Y, F.Y);
- WHILE x > y DO
- INC(d, dy); INC(dy, 8); INC(y);
- IF d >= 0 THEN
- Line2o(X-x-1, Y-y, Y+yb, 2*(x+1), y-yb);
- Line2o(X-y, Y-x-1, Y+x, 2*y, 1);
- DEC(d, dx); DEC(dx, 8); DEC(x); yb := y
- END
- END;
- IF x = y THEN INC(y); Line2o(X-x-1, Y-y, Y+yb, 2*(x+1), y-yb) END;
- (* inner circle *)
- x := Ri; y := 0; dx := 8*(x-1); dy := 8*y+4; d := 1 - 4*Ri; yb := 0;
- WHILE x > y DO
- INC(d, dy); INC(dy, 8); INC(y);
- IF d >= 0 THEN
- Line2i(X-x-1, Y-y, Y+yb, 2*(x+1), y-yb);
- Line2i(X-y, Y-x-1, Y+x, 2*y, 1);
- DEC(d, dx); DEC(dx, 8); DEC(x); yb := y
- END
- END;
- IF x = y THEN INC(y); Line2i(X-x-1, Y-y, Y+yb, 2*(x+1), y-yb) END;
- (* drawing *)
- ScanLines(F, Y-R-1, 2*R+2, F.Y, col, X0, Y0)
- END
- END ThickCircle;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- VAR x, y, xb, yb: INTEGER; d, dx, dy, x2, y2, a, a2, a8, b, b2, b8: LONGINT;
- BEGIN
- IF (A > 0) & (B > 0) THEN DEC(A); DEC(Ai); DEC(B); DEC(Bi);
- a := A; a2 := a*a; a8 := 8*a2; b := B; b2 := b*b; b8 := 8*b2;
- x := A; y := 0; x2 := a*b2; y2 := 0; dx := b8*(a-1); dy := 4*a2; d := b2*(1- 4*a); yb := 0;
- IF (Ai < 0) OR (Bi < 0) THEN (* filled ellipse *)
- WHILE y2 < x2 DO
- INC(d, dy); INC(dy, a8); INC(y); INC(y2, a2);
- IF d >= 0 THEN
- Line2(F, X-x-1, Y-y, Y+yb, 2*(x+1), y-yb, col, X0, Y0);
- DEC(d, dx); DEC(dx, b8); DEC(x); DEC(x2, b2); yb := y
- END
- END;
- IF y > yb THEN Line2(F, X-x-1, Y-y-1, Y+yb, 2*(x+1), y-yb+1, col, X0, Y0) END;
- INC(d, 4*(x2+y2)-b2+a2); xb := x;
- WHILE x >= 0 DO
- DEC(d, dx); DEC(dx, b8); DEC(x);
- IF d < 0 THEN
- Line2(F, X-xb-1, Y-y-1, Y+y, 2*(xb+1), 1, col, X0, Y0);
- INC(d, dy); INC(dy, a8); INC(y); xb := x
- END
- END;
- IF x < xb THEN Line2(F, X-xb-1, Y-y-1, Y+y, 2*(xb+1), 1, col, X0, Y0) END
- ELSE (* outer ellipse *)
- DEC(Y, F.Y);
- WHILE y2 < x2 DO
- INC(d, dy); INC(dy, a8); INC(y); INC(y2, a2);
- IF d >= 0 THEN
- Line2o(X-x-1, Y-y, Y+yb, 2*(x+1), y-yb);
- DEC(d, dx); DEC(dx, b8); DEC(x); DEC(x2, b2); yb := y
- END
- END;
- IF y > yb THEN Line2o(X-x-1, Y-y-1, Y+yb, 2*(x+1), y-yb+1) END;
- INC(d, 4*(x2+y2)-b2+a2); xb := x;
- WHILE x >= 0 DO
- DEC(d, dx); DEC(dx, b8); DEC(x);
- IF d < 0 THEN
- Line2o(X-xb-1, Y-y-1, Y+y, 2*(xb+1), 1);
- INC(d, dy); INC(dy, a8); INC(y); xb := x
- END
- END;
- IF x < xb THEN Line2o(X-xb-1, Y-y-1, Y+y, 2*(xb+1), 1) END;
- (* inner ellipse *)
- a := Ai; a2 := a*a; a8 := 8*a2; b := Bi; b2 := b*b; b8 := 8*b2;
- x := Ai; y := 0; x2 := a*b2; y2 := 0; dx := b8*(a-1); dy := 4*a2; d := b2*(1- 4*a); yb := 0;
- WHILE y2 < x2 DO
- INC(d, dy); INC(dy, a8); INC(y); INC(y2, a2);
- IF d >= 0 THEN
- Line2i(X-x-1, Y-y, Y+yb, 2*(x+1), y-yb);
- DEC(d, dx); DEC(dx, b8); DEC(x); DEC(x2, b2); yb := y
- END
- END;
- IF y > yb THEN Line2i(X-x-1, Y-y-1, Y+yb, 2*(x+1), y-yb+1) END;
- INC(d, 4*(x2+y2)-b2+a2); xb := x;
- WHILE x >= 0 DO
- DEC(d, dx); DEC(dx, b8); DEC(x);
- IF d < 0 THEN
- Line2i(X-xb-1, Y-y-1, Y+y, 2*(xb+1), 1);
- INC(d, dy); INC(dy, a8); INC(y); xb := x
- END
- END;
- IF x < xb THEN Line2i(X-xb-1, Y-y-1, Y+y, 2*(xb+1), 1) END;
- (* drawing *)
- ScanLines(F, Y-B-1, 2*B+2, F.Y, col, X0, Y0)
- END
- END
- END ThickEllipse;
- Syntax10i.Scn.Fnt
- VAR X0, Y0, X1, Y1, X2, Y2, X1i, Y1i, X2i, Y2i, A, B, Ai, Bi: INTEGER;
- line: ARRAY 4096 OF RECORD x1, x2, x3, x4: INTEGER END;
- Dot: DotProc; Block: BlockProc; mode: INTEGER;
- PROCEDURE HairCircle (F: Display.Frame; X, Y, R, col: INTEGER);
- PROCEDURE HairEllipse (F: Display.Frame; X, Y, A, B, col: INTEGER);
- PROCEDURE Line2 (F: Display.Frame; x, y1, y2, w, h, col, X0, Y0: INTEGER);
- PROCEDURE Line2o (x, y1, y2, w, h: INTEGER);
- PROCEDURE Line2i (x, y1, y2, w, h: INTEGER);
- PROCEDURE ScanLines (F: Display.Frame; y, h, y0, col, X0, Y0: INTEGER);
- PROCEDURE ThickCircle (F: Display.Frame; X, Y, R, Ri, col, X0, Y0: INTEGER);
- PROCEDURE ThickEllipse (F: Display.Frame; X, Y, A, B, Ai, Bi, col, X0, Y0: INTEGER);
- BEGIN
- Scale(F, x-a, y-b, X1, Y1);
- Scale(F, x+a, y+b, X2, Y2);
- IF (F.X < X2) & (X1 < F.X + F.W) & (F.Y < Y2) & (Y1 < F.Y + F.H) THEN (* ellipse may be visible *)
- SetUp(F, Dot, Block, col, mode, pat);
- A := (X2-X1) DIV 2; B := (Y2-Y1) DIV 2;
- IF d <= 0 THEN (* hair ellipse *)
- IF A = B THEN HairCircle(F, X1+A, Y1+B, A, col)
- ELSE HairEllipse(F, X1+A, Y1+B, A, B, col)
- END
- ELSE (* thick ellipse *)
- Scale(F, 0, 0, X0, Y0);
- Scale(F, x-a+d, y-b+d, X1i, Y1i);
- Scale(F, x+a-d, y+b-d, X2i, Y2i);
- Ai := (X2i-X1i) DIV 2; Bi := (Y2i-Y1i) DIV 2;
- IF (A = B) & (Ai = Bi) THEN ThickCircle(F, X1+A, Y1+B, A, Ai, col, X0, Y0)
- ELSE ThickEllipse(F, X1+A, Y1+B, A, B, Ai, Bi, col, X0, Y0)
- END
- END
- END
- END Ellipse;
- MODULE GraphicOps; (* gri 25 Jan 93 *)
- IMPORT Input, Display, Pluto := Printer, MathL;
- CONST
- invert* = -1;
- TYPE
- DotProc = PROCEDURE (F: Display.Frame; col, X, Y, mode: INTEGER);
- BlockProc = PROCEDURE (F: Display.Frame; col: INTEGER; pat: LONGINT; X, Y, W, H, Xp, Yp, mode: INTEGER);
- Scale*: PROCEDURE (F: Display.Frame; x, y: LONGINT; VAR X, Y: INTEGER);
- Screen*: Display.Frame;
- Printer*: Display.Frame;
- PROCEDURE StdScale (F: Display.Frame; x, y: LONGINT; VAR X, Y: INTEGER);
- PROCEDURE PDot (F: Display.Frame; col, X, Y, mode: INTEGER);
- PROCEDURE DBlock (F: Display.Frame; col: INTEGER; pat: LONGINT; X, Y, W, H, Xp, Yp, mode: INTEGER);
- PROCEDURE PBlock (F: Display.Frame; col: INTEGER; pat: LONGINT; X, Y, W, H, Xp, Yp, mode: INTEGER);
- PROCEDURE SetUp (F: Display.Frame; VAR Dot: DotProc; VAR Block: BlockProc; col: INTEGER; VAR mode: INTEGER;
- pat: Display.Pattern);
- PROCEDURE Quadrangle* (F: Display.Frame; x1, y1, x2, y2, x3, y3, x4, y4, pat: LONGINT; col: INTEGER);
- PROCEDURE Line* (F: Display.Frame; x1, y1, x2, y2, d, pat: LONGINT; col: INTEGER);
- PROCEDURE Rect* (F: Display.Frame; x, y, w, h, d, pat: LONGINT; col: INTEGER);
- PROCEDURE Ellipse* (F: Display.Frame; x, y, a, b, d, pat: LONGINT; col: INTEGER);
- BEGIN
- Scale := StdScale;
- NEW(Screen); Screen.X := 0; Screen.Y := 0; Screen.W := Display.Width; Screen.H := Display.Height;
- NEW(Printer); Printer.X := 0; Printer.Y := 0; Printer.W := 2200; Printer.H := 3300
- END GraphicOps.
-